package com.xzzz.backend.bsms.config;

import com.power.doc.builder.HtmlApiDocBuilder;
import com.power.doc.model.*;
import com.xzzz.common.base.config.SmartDocConstants;
import com.xzzz.common.base.enums.YesNo;
import com.xzzz.common.base.pojo.RCode;
import com.xzzz.irda.auth.core.constants.GrantTypeEnum;
import com.xzzz.irda.auth.core.exception.AuthRCode;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * Smart-Doc 文档生成工具
 * <p><a href="https://smart-doc-group.github.io/#/zh-cn/diy/highlight">官方文档地址</a>
 * <p>
 * <p> 使用 Smart-Doc 时重写了 html 页面样式，使之更符合中文阅读习惯。
 * <p> 在使用前需要先编译 smart-doc 项目，使用如下命令：
 * <pre>mvn clean install -Dmaven.test.skip=true -Dfile.encoding=UTF-8 -Dmaven.javadoc.skip=true </pre>
 * <p>
 * <p> 编译后执行该方法生成 html 接口文件，访问 http://localhost:19021/apidoc/index.html 链接查看文档
 */
@Slf4j
public class BsmsApiDocGen {

    private static String SEPARATOR = "===============================================================================";

    private static final List<String> sourceCodePath = new ArrayList<String>() {{
        this.add("backend-bsms/src/main/java/com/xzzz/backend/bsms");
        this.addAll(SmartDocConstants.sourceCodePath);
    }};

    public static void main(String[] args) {
        genDoc();
    }

    public static void genDoc() {
        log.warn("生成接口文档");
        ApiConfig config = new ApiConfig();
        config.setProjectCName("后台管理监控服务");
        config.setProjectName("backend-bsms");
        config.setOutPath("backend-bsms/src/main/resources/static/apidoc");
        config.setServerUrl("http://127.0.0.1:19009");
        config.setStyle("darcula"); // 另一个代码块样式 solarized-light
        config.setAllInOne(true);
        // 创建一个类似swagger的可调试接口的文档页面, 仅在AllInOne模式中起作用。
        config.setCreateDebugPage(false);
        // 请求示例
        config.setRequestExample(true);
        // 设置为 true 会将枚举详情展示到参数表中, 默认关闭
        config.setInlineEnum(true);
        // 是否显示接口作者名称
        config.setShowAuthor(false);
        // 配置true会在注释栏自动显示泛型的真实类型短类名
        config.setDisplayActualType(true);
        // 文件名
        config.setAllInOneDocFileName("index.html");
        // 源码扫描地址
        config.setSourceCodePaths(sourceCodePath());
        // api分组
        config.setGroups(groups());
        // 数据字典
        config.setDataDictionaries(dataDict());
        // 错误码列表
        config.setErrorCodeDictionaries(errorCodes());
        // 版本更新日志
        config.setRevisionLogs(revisions());

        System.out.println(SEPARATOR);
        System.out.println("正在生成 Html 接口文档...");
        HtmlApiDocBuilder.buildApiDoc(config);
    }

    private static List<SourceCodePath> sourceCodePath() {
        List<SourceCodePath> results = new ArrayList<>();
        for (String s : sourceCodePath) {
            SourceCodePath path = new SourceCodePath();
            path.setPath(s);
            results.add(path);
        }
        return results;
    }

    private static List<ApiGroup> groups() {
        List<ApiGroup> results = new ArrayList<>();
        ApiGroup commonBase = new ApiGroup();
        commonBase.setName("【common】公共接口");
        commonBase.setApis("com.xzzz.common.*");
        results.add(commonBase);

        ApiGroup base = new ApiGroup();
        base.setName("【bsms】系统管理服务");
        base.setApis("com.xzzz.backend.bsms.*");
        results.add(base);

        ApiGroup redis = new ApiGroup();
        redis.setName("【Redis】Redis监控模块");
        redis.setApis("com.xzzz.irda.guardcat.server.metric.redis");
        results.add(redis);

        ApiGroup guardcat = new ApiGroup();
        guardcat.setName("【GuardCat】公共监控模块");
        guardcat.setApis("com.xzzz.irda.guardcat.*");
        results.add(guardcat);

        ApiGroup tracker = new ApiGroup();
        tracker.setName("【Trackers】链路追踪模块");
        tracker.setApis("com.xzzz.irda.tracker.*");
        results.add(tracker);

        ApiGroup sentinel = new ApiGroup();
        sentinel.setName("【Sentinel】流量监控模块");
        sentinel.setApis("com.xzzz.expand.sentinel.metric.*");
        results.add(sentinel);

//        ApiGroup nacos = new ApiGroup();
//        nacos.setName("【Common-Nacos】服务发现模块 ");
//        nacos.setApis("com.xzzz.common.nacos.*");
//        results.add(nacos);

        return results;
    }

    private static List<ApiDataDictionary> dataDict() {
        List<ApiDataDictionary> results = new ArrayList<>();

        ApiDataDictionary dictGrantType = new ApiDataDictionary();
        dictGrantType.setTitle("登录方式 [GrantType]");
        dictGrantType.setEnumClass(GrantTypeEnum.class);
        dictGrantType.setCodeField("type");
        dictGrantType.setDescField("desc");
        results.add(dictGrantType);


        ApiDataDictionary yesNo = new ApiDataDictionary();
        yesNo.setTitle("是否,真假字典 [YesNo]");
        yesNo.setEnumClass(YesNo.class);
        yesNo.setCodeField("value");
        yesNo.setDescField("name");
        results.add(yesNo);
        return results;
    }

    /**
     * 版本说明
     */
    private static List<RevisionLog> revisions() {
        List<RevisionLog> visions = new ArrayList<>();
        RevisionLog apiUrl = new RevisionLog();
        apiUrl.setVersion(SmartDocConstants.apiUriVersion);
        apiUrl.setRemarks("开发环境: http://127.0.0.1:19009");
        visions.add(apiUrl);

        RevisionLog authHowToUse = new RevisionLog();
        authHowToUse.setVersion(SmartDocConstants.authHowToUseVersion);
        authHowToUse.setRemarks(SmartDocConstants.authHowToUseRemarks);
        visions.add(authHowToUse);


        RevisionLog standards = new RevisionLog();
        standards.setVersion(SmartDocConstants.standardsVersion);
        standards.setRemarks(SmartDocConstants.standardsRemarks);
        visions.add(standards);

        RevisionLog docHelp = new RevisionLog();
        docHelp.setVersion(SmartDocConstants.docHelpVersion);
        docHelp.setRemarks(SmartDocConstants.docHelpRemarks);
        visions.add(docHelp);

        RevisionLog invokeHelp = new RevisionLog();
        invokeHelp.setVersion(SmartDocConstants.invokeHelpVersion);
        invokeHelp.setRemarks(SmartDocConstants.invokeHelpRemarks);
        visions.add(invokeHelp);
        return visions;
    }


    private static List<ApiErrorCodeDictionary> errorCodes() {
        List<ApiErrorCodeDictionary> results = new ArrayList<>();

        ApiErrorCodeDictionary dict1 = new ApiErrorCodeDictionary();
        dict1.setEnumClass(RCode.class);
        dict1.setCodeField("code");
        dict1.setDescField("msg");
        results.add(dict1);

        ApiErrorCodeDictionary dict2 = new ApiErrorCodeDictionary();
        dict2.setEnumClass(AuthRCode.class);
        dict2.setCodeField("code");
        dict2.setDescField("desc");
        results.add(dict2);

        return results;
    }
}
